package net.lcqf.websocket.server;


import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.concurrent.GlobalEventExecutor;
import net.lcqf.websocket.game.RoomManager;
import net.lcqf.websocket.send.MessageFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * +----------------------------------------------------------------------
 * // | Talk To [ 聊来改善地区金融服务环境，助力企业发展 ]
 * // +----------------------------------------------------------------------
 * // | Copyright (c) 2021-2025 聊来 All rights reserved.
 * // +----------------------------------------------------------------------
 * // | Licensed ( <a href="http://www.apache.org/licenses/LICENSE-2.0">apache</a> )
 * // +----------------------------------------------------------------------
 * // | @Author: 聊来 <18970881148@qq.com>
 * // +----------------------------------------------------------------------
 * // | DateTime: 2025/4/15 17:15
 * // +----------------------------------------------------------------------
 */

@Component
public class WebSocketServerHandler extends SimpleChannelInboundHandler<MsgInfoPojo.MsgInfo> {

    private final Logger logger = LoggerFactory.getLogger(WebSocketServerHandler.class);

    private MessageFactory messageFactory;
    @Autowired
    public void SetMessageChannel(MessageFactory messageFactory) {
        this.messageFactory = messageFactory;
    }

    private static WebSocketServerHandler handler = null;
    @PostConstruct
    public void init() {
        if (handler == null) { handler = this; }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        logger.info("客户端建立WebSocket连接，通道开启：" + ctx.channel());
    }

    /**
     * 客户端与服务器断开连接的时候触发
     * @param ctx ChannelHandlerContext
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        RoomManager.room.values().forEach(set -> set.remove(ctx.channel()));
        logger.info("客户端断开WebSocket连接，通道关闭：" + ctx.channel());
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, MsgInfoPojo.MsgInfo msg) throws Exception {
        //logger.info("接收客户端发送的消息：" + msg);

        Object data = handler.messageFactory.sendMessage(ctx.channel(), msg);
        if (ObjectUtil.isNotNull(data)) {
            MsgInfoPojo.MsgInfo response = MsgInfoPojo.MsgInfo.newBuilder()
                    .setRequestType(msg.getRequestType())
                    .setData(JSONUtil.toJsonStr(data))
                    .build();
            ctx.channel().writeAndFlush(response);
        }
    }

    /**
     * 消息收、发完成
     * @param ctx ChannelHandlerContext
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) { ctx.flush(); }

    /**
     * 服务器与客户端长连接，进行心跳检测
     * @param ctx ChannelHandlerContext
     * @param evt Object
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent stateEvent = (IdleStateEvent) evt;
            if (stateEvent.state() == IdleState.READER_IDLE) {
                RoomManager.room.values().forEach(set -> set.remove(ctx.channel()));
                ctx.channel().close();
            }
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.error("消息异常：" + cause.getMessage());
        cause.printStackTrace();

        //if (ctx.channel().isActive()) { ctx.channel().close(); }
    }
}
